#include "ThreadCache.h"
#include "CentralCache.h"

void *TreadCache::Allocate(size_t size)
{
    assert(_freeList);
    // 算出在哪个桶
    // 若有空间直接给，没有找CentralCache要
    size_t alignBity = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if (_freeList[index].Empty())
    {
        return FetchFromCentralCache(index, alignBity);
    }

    return _freeList[index].Pop();
}

// 从centraCache要空间
void *TreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAXBITYS);

    size_t bachNum = std::min(SizeClass::HowManyNumObj(size), ThresholdValue);
    // 慢启动增长
    ThresholdValue += 1;

    void *start = nullptr;
    void *end = nullptr;
    // 函数内部上锁
    size_t num = CentralCache::GetInstance()->FetchRangeObj(start, end, bachNum, size);

    //取走1个，剩下的插入_freeList里
    if(num == 1)
    {
        return start;
    }
    else{
        _freeList[index].PushNumObj(NextObj(start), end, num-1);
        return start;
    }
}

void TreadCache::Dellocate(void *obj, size_t size)
{
    assert(obj);
    assert(size <= MAXBITYS);
    size_t index = SizeClass::Index(size);
    _freeList[index].Push(obj);

    // 判断是否要回收内存
    if (_freeList[index].IsFreeObjToCentral(ThresholdValue))
    {
        ListToLong(_freeList[index],size);
    }
}
void TreadCache::ListToLong(FreeList& List,size_t size)
{
        void* start = nullptr;
        void* end = nullptr; 
        List.PopNumObj(start, end,ThresholdValue);
        // 还内存给CentralCache
        CentralCache::GetInstance()->ObjGiveBack(size, start);
}
